package org.light.utils;

import java.util.List;

import org.light.core.LayoutComb;
import org.light.core.ReportComb;
import org.light.domain.Domain;
import org.light.domain.Field;
import org.light.domain.Project;
import org.light.exception.ValidateException;
import org.light.layouts.ParentChildGridLayout;
import org.light.layouts.TreeGridLayout;
import org.light.layouts.TreeParentChildLayout;
import org.light.reports.EChartsCompareGridReport;
import org.light.reports.EChartsGridReport;
import org.light.reports.EChartsReport;
import org.light.simpleauth.SimpleAuthModule;

public class CompareUtil {
	public static boolean compareField(Field baselineField,Field originalField) {
		if (baselineField == null && originalField == null) return true;
		if ((baselineField != null && originalField == null) || (baselineField == null && originalField != null)) return false;
		if (!baselineField.getFieldName().equals(originalField.getFieldName())) return false;
		if (!FieldUtil.isSameType(baselineField, originalField)) return false;
		return true;
	}
	
	public static boolean compareDomain(Domain baselineDomain, Domain originalDomain) throws ValidateException{
		if (!baselineDomain.getStandardName().equals(originalDomain.getStandardName())) return false;
		if (!baselineDomain.getPlural().equals(originalDomain.getPlural())) return false;
		if (!DeniableUtils.isSameDenyString(baselineDomain.getVerbDeniesStr(),originalDomain.getVerbDeniesStr())) return false;
		if (!compareField(baselineDomain.getDomainId(),originalDomain.getDomainId())) return false;
		if (!compareField(baselineDomain.getDomainName(),originalDomain.getDomainName())) return false;
		if (!compareField(baselineDomain.getActive(),originalDomain.getActive())) return false;
		for (Field fb:baselineDomain.getPlainFields()) {
			Field fo = DomainUtil.findDomainFieldByFieldName(originalDomain, fb.getFieldName());
			if (fo == null) return false;
			if (!compareField(fb,fo)) return false;
		}
		for (Field fo:originalDomain.getPlainFields()) {
			Field fb = DomainUtil.findDomainFieldByFieldName(baselineDomain, fo.getFieldName());
			if (fb == null) return false;
			if (!compareField(fo,fb)) return false;
		}
		return true;
	}
	
	public static LayoutComb findLayoutInsideListOrReturnNull(List<LayoutComb> lcl,LayoutComb mylayout) {
		for (LayoutComb lc:lcl) {
			if (lc instanceof ParentChildGridLayout && mylayout instanceof ParentChildGridLayout &&
				((ParentChildGridLayout) lc).getParentDomain().getStandardName().equals(((ParentChildGridLayout) mylayout).getParentDomain().getStandardName()) &&
				((ParentChildGridLayout) lc).getChildDomain().getStandardName().equals(((ParentChildGridLayout) mylayout).getChildDomain().getStandardName())) return lc;
			else if (lc instanceof TreeGridLayout && mylayout instanceof TreeGridLayout &&
					((TreeGridLayout) lc).getParentTreeDomain().getStandardName().equals(((TreeGridLayout) mylayout).getParentTreeDomain().getStandardName()) &&
					((TreeGridLayout) lc).getChildDomain().getStandardName().equals(((TreeGridLayout) mylayout).getChildDomain().getStandardName())) return lc;
			else if (lc instanceof TreeParentChildLayout && mylayout instanceof TreeParentChildLayout &&
					((TreeParentChildLayout) lc).getTreeDomain().getStandardName().equals(((TreeParentChildLayout) mylayout).getTreeDomain().getStandardName()) &&
					((TreeParentChildLayout) lc).getParentDomain().getStandardName().equals(((TreeParentChildLayout) mylayout).getParentDomain().getStandardName()) &&
					((TreeParentChildLayout) lc).getChildDomain().getStandardName().equals(((TreeParentChildLayout) mylayout).getChildDomain().getStandardName())) return lc;
		}
		return null;
	}
	
	public static String compareProject(Project baselineProject,Project originalProject) throws ValidateException{
		StringBuilder sb = new StringBuilder();
		if (!baselineProject.getStandardName().equalsIgnoreCase(originalProject.getStandardName())) throw new ValidateException("两项目名字不一致。");
		if (!baselineProject.getTechnicalstack().equalsIgnoreCase(originalProject.getTechnicalstack())) throw new ValidateException("两项目技术栈不一致。");
		for (Domain dmb:baselineProject.getDomains()) {
			Domain dmo = DomainUtil.findDomainInListOrReturnNull(originalProject.getDomains(),dmb.getStandardName());
			if (dmo == null) sb.append(dmb.getStandardName()).append(",");
			if (!compareDomain(dmb,dmo)) sb.append(dmb.getStandardName()).append(",");
		}
		if (baselineProject.getModules()!=null && originalProject.getModules()==null) sb.append("ShiroAuth").append(",");
		if (baselineProject.getModules()!=null && originalProject.getModules()!=null) {
			SimpleAuthModule bsam = (SimpleAuthModule)baselineProject.getModules().get(0);
			SimpleAuthModule osam = (SimpleAuthModule)originalProject.getModules().get(0);
			if (!compareDomain(bsam.getUserDomain(),osam.getUserDomain()))  sb.append("ShiroAuth").append(",");
			else if (!compareDomain(bsam.getRoleDomain(),osam.getRoleDomain()))  sb.append("ShiroAuth").append(",");
			else if (!compareDomain(bsam.getPrivilegeDomain(),osam.getPrivilegeDomain()))  sb.append("ShiroAuth").append(",");
		}
		
		for (LayoutComb blc : baselineProject.getLayoutCombs()) {
			LayoutComb olc = findLayoutInsideListOrReturnNull(originalProject.getLayoutCombs(),blc);
			if (olc == null) sb.append(blc.getStandardName()).append(",");
			else if (!compareLayoutComb(blc,olc)) sb.append(blc.getStandardName()).append(",");
		}
		
		for (ReportComb brc : baselineProject.getReportCombs()) {
			ReportComb orc = findReportInsideListOrReturnNull(originalProject.getReportCombs(),brc);
			if (orc == null) sb.append(brc.getStandardName()).append(",");
			else if (!compareReportComb(brc,orc)) sb.append(brc.getStandardName()).append(",");
		}
		
		return sb.toString();
	}

	private static boolean compareReportComb(ReportComb brc, ReportComb orc) throws ValidateException{
		if (!brc.getStandardName().equals(orc.getStandardName())) return false;
		if (brc instanceof EChartsReport && orc  instanceof EChartsReport) {
			if (!compareDomain(((EChartsReport)brc).getReportDomain(),((EChartsReport)orc).getReportDomain())){
				return false;
			}
		} if (brc instanceof EChartsGridReport && orc  instanceof EChartsGridReport) {
			if (!compareDomain(((EChartsGridReport)brc).getReportDomain(),((EChartsGridReport)orc).getReportDomain())){
				return false;
			}
		}else if (brc instanceof EChartsCompareGridReport && orc  instanceof EChartsCompareGridReport) {
			if (!compareDomain(((EChartsCompareGridReport)brc).getPlanDomain(),((EChartsCompareGridReport)orc).getPlanDomain())){
				return false;
			} else if (!compareDomain(((EChartsCompareGridReport)brc).getActionDomain(),((EChartsCompareGridReport)orc).getActionDomain())){
				return false;
			}
		}
		return true;
	}

	private static ReportComb findReportInsideListOrReturnNull(List<ReportComb> reportCombs, ReportComb myreport) {
		for (ReportComb rc:reportCombs) {
			if (rc instanceof EChartsReport && myreport instanceof EChartsReport &&
				((EChartsReport) rc).getReportDomain().getStandardName().equals(((EChartsReport) myreport).getReportDomain().getStandardName())) return rc;
			else if (rc instanceof EChartsGridReport && myreport instanceof EChartsGridReport &&
					((EChartsGridReport) rc).getReportDomain().getStandardName().equals(((EChartsGridReport) myreport).getReportDomain().getStandardName())) return rc;
			else if (rc instanceof EChartsCompareGridReport && myreport instanceof EChartsCompareGridReport &&
					((EChartsCompareGridReport) rc).getPlanDomain().getStandardName().equals(((EChartsCompareGridReport) myreport).getPlanDomain().getStandardName())&&
					((EChartsCompareGridReport) rc).getActionDomain().getStandardName().equals(((EChartsCompareGridReport) myreport).getActionDomain().getStandardName())) return rc;
		}
		return null;
	}

	private static boolean compareLayoutComb(LayoutComb blc, LayoutComb olc) throws ValidateException {
		if (!blc.getStandardName().equals(olc.getStandardName())) return false;
		if (blc instanceof ParentChildGridLayout && olc  instanceof ParentChildGridLayout) {
			if (!compareDomain(((ParentChildGridLayout)blc).getParentDomain(),((ParentChildGridLayout)olc).getParentDomain())){
				return false;
			}else if (!compareDomain(((ParentChildGridLayout)blc).getChildDomain(),((ParentChildGridLayout)olc).getChildDomain())){
				return false;
			}
		} else if (blc instanceof TreeGridLayout && olc  instanceof TreeGridLayout) {
			if (!compareDomain(((TreeGridLayout)blc).getParentTreeDomain(),((TreeGridLayout)olc).getParentTreeDomain())){
				return false;
			}else if (!compareDomain(((TreeGridLayout)blc).getChildDomain(),((TreeGridLayout)olc).getChildDomain())){
				return false;
			}
		}else if (blc instanceof TreeParentChildLayout && olc  instanceof TreeParentChildLayout) {
			if (!compareDomain(((TreeParentChildLayout)blc).getTreeDomain(),((TreeParentChildLayout)olc).getTreeDomain())){
				return false;
			}else if (!compareDomain(((TreeParentChildLayout)blc).getParentDomain(),((TreeParentChildLayout)olc).getParentDomain())){
				return false;
			}else if (!compareDomain(((TreeParentChildLayout)blc).getChildDomain(),((TreeParentChildLayout)olc).getChildDomain())){
				return false;
			}
		}
		return true;
	}
}
